package com.wali.common.web;

import com.alibaba.fastjson.JSONObject;
import com.wali.common.ccp.exception.CcpException;
import com.wali.common.ccp.execl.CcpExcelReport;
import com.wali.common.ccp.json.CcpFastjsonkMapper;
import com.wali.common.consts.CommonConsts;
import com.wali.common.enums.ErrorCodeEnum;
import com.wali.common.enums.ModulesEnum;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * @ClassName: BaseController
 * @Description: Controller基类
 * @author: wali
 * @email wali.xu@kpmg.com
 * @date: 19/07/2018 11:47 上午
 */
public abstract class BaseController {
    /**
     * 日志对象
     */
    protected Logger logger = LoggerFactory.getLogger(getClass());

    /**
     * @Title: getResponseEntity
     * @Description: 返回code
     * @param: code
     * @return: ResponseEntity
     * @throws:
     */
    protected ResponseEntity<String> getResponseEntity(int code) {
        HttpHeaders responseHeaders = new HttpHeaders();
        responseHeaders.set("Content-Type", "application/json; charset=utf-8");

        Map<String, Object> map = new HashMap<>();
        map.put(CommonConsts.MSG_CODE, code);

        String responseMsg;
        try {
            responseMsg = CcpFastjsonkMapper.convertObjectToString(map);
        } catch (CcpException e) {
            logger.error(ModulesEnum.CCP.name(), e);
            responseMsg = CommonConsts.RPS_MSG_TEMPLATE.replace(CommonConsts.CHARACTER_INTERROGATION,
                    ErrorCodeEnum.ERROR_INTERNAL_CODE.name());
        }

        logger.info(responseMsg);

        return new ResponseEntity<>(responseMsg, responseHeaders, HttpStatus.OK);
    }

    /**
     * @Title: getResponseEntity
     * @Description: 直接返回数据
     * @param: data
     * @return: ResponseEntity
     * @throws:
     */
    protected ResponseEntity<String> getResponseEntity(Object data) {
        HttpHeaders responseHeaders = new HttpHeaders();
        responseHeaders.set("Content-Type", "application/json; charset=utf-8");

        String responseMsg;
        try {
            responseMsg = CcpFastjsonkMapper.convertObjectToString(data);
        } catch (CcpException e) {
            logger.error(ModulesEnum.CCP.name(), e);
            responseMsg = CommonConsts.RPS_MSG_TEMPLATE.replace(CommonConsts.CHARACTER_INTERROGATION,
                    ErrorCodeEnum.ERROR_INTERNAL_CODE.name());
        }

        logger.info(responseMsg);

        return new ResponseEntity<>(responseMsg, responseHeaders, HttpStatus.OK);
    }

    /**
     * @Title: getResponseEntity
     * @Description: 不封装数据，直接返回
     * @param: code
     * @param: msg
     * @return: ResponseEntity
     * @throws:
     */
    protected ResponseEntity<String> getResponseEntity(int code, String msg) {
        HttpHeaders responseHeaders = new HttpHeaders();
        responseHeaders.set("Content-Type", "application/json; charset=utf-8");

        Map<String, Object> map = new HashMap<>();
        map.put(CommonConsts.MSG_CODE, code);
        map.put(CommonConsts.MSG_MSG, msg);

        String responseMsg;
        try {
            responseMsg = CcpFastjsonkMapper.convertObjectToString(map);
        } catch (CcpException e) {
            logger.error(ModulesEnum.CCP.name(), e);
            responseMsg = CommonConsts.RPS_MSG_TEMPLATE.replace(CommonConsts.CHARACTER_INTERROGATION,
                    ErrorCodeEnum.ERROR_INTERNAL_CODE.name());
        }

        logger.info(responseMsg);

        return new ResponseEntity<>(responseMsg, responseHeaders, HttpStatus.OK);
    }

    /**
     * @Title: getResponseEntity
     * @Description: 不封装数据，直接返回
     * @param: code
     * @param: data
     * @return: ResponseEntity
     * @throws:
     */
    protected ResponseEntity<String> getResponseEntity(int code, Object data) {
        HttpHeaders responseHeaders = new HttpHeaders();
        responseHeaders.set("Content-Type", "application/json; charset=utf-8");

        Map<String, Object> map = new HashMap<>();
        map.put(CommonConsts.MSG_CODE, code);
        map.put(CommonConsts.MSG_DATA, data);

        String responseMsg;
        try {
            responseMsg = CcpFastjsonkMapper.convertObjectToString(map);
        } catch (CcpException e) {
            logger.error(ModulesEnum.CCP.name(), e);
            responseMsg = CommonConsts.RPS_MSG_TEMPLATE.replace(CommonConsts.CHARACTER_INTERROGATION,
                    ErrorCodeEnum.ERROR_INTERNAL_CODE.name());
        }

        logger.info(responseMsg);

        return new ResponseEntity<>(responseMsg, responseHeaders, HttpStatus.OK);
    }

    /**
     * @Title: getResponseEntity
     * @Description: 不封装数据，直接返回
     * @param: code
     * @param: msg
     * @param: data
     * @return: ResponseEntity
     * @throws:
     */
    protected ResponseEntity<String> getResponseEntity(int code, int count, Object data) {
        HttpHeaders responseHeaders = new HttpHeaders();
        responseHeaders.set("Content-Type", "application/json; charset=utf-8");

        Map<String, Object> map = new HashMap<>();
        map.put(CommonConsts.MSG_CODE, code);
        map.put(CommonConsts.MSG_COUNT, count);
        map.put(CommonConsts.MSG_DATA, data);

        String responseMsg;
        try {
            responseMsg = CcpFastjsonkMapper.convertObjectToString(map);
        } catch (CcpException e) {
            logger.error(ModulesEnum.CCP.name(), e);
            responseMsg = CommonConsts.RPS_MSG_TEMPLATE.replace(CommonConsts.CHARACTER_INTERROGATION,
                    ErrorCodeEnum.ERROR_INTERNAL_CODE.name());
        }

        logger.info(responseMsg);

        return new ResponseEntity<>(responseMsg, responseHeaders, HttpStatus.OK);
    }

    /**
     * @Title: getResponseEntity
     * @Description: 不封装数据，直接返回
     * @param: code
     * @param: msg
     * @param: data
     * @return: ResponseEntity
     * @throws:
     */
    protected ResponseEntity<String> getResponseEntity(int code, String msg, Object data) {
        HttpHeaders responseHeaders = new HttpHeaders();
        responseHeaders.set("Content-Type", "application/json; charset=utf-8");

        Map<String, Object> map = new HashMap<>();
        map.put(CommonConsts.MSG_CODE, code);
        map.put(CommonConsts.MSG_MSG, msg);
        map.put(CommonConsts.MSG_DATA, data);

        String responseMsg;
        try {
            responseMsg = CcpFastjsonkMapper.convertObjectToString(map);
        } catch (CcpException e) {
            logger.error(ModulesEnum.CCP.name(), e);
            responseMsg = CommonConsts.RPS_MSG_TEMPLATE.replace(CommonConsts.CHARACTER_INTERROGATION,
                    ErrorCodeEnum.ERROR_INTERNAL_CODE.name());
        }

        logger.info(responseMsg);
        return new ResponseEntity<>(responseMsg, responseHeaders, HttpStatus.OK);
    }

    /**
     * @Title: getObjectFromReq
     * @Description: 从reqquest中获取指定类型的对象
     * @param: req
     * @param: requireType
     * @return: T
     * @throws:
     */
    protected <T> T getObjectFromReq(HttpServletRequest req, Class<T> requiredType) throws Exception {
        Map paramsMap = req.getParameterMap();

        JSONObject json = new JSONObject();
        Iterator it = paramsMap.keySet().iterator();
        while (it.hasNext()) {
            String key = it.next().toString();
            String[] values = (String[]) paramsMap.get(key);
            json.put(key, values[0]);
        }

        return CcpFastjsonkMapper.convertStringToObject(json.toJSONString(), requiredType);
    }

    /**
     * @Title: write
     * @Description: 不封装数据，直接返回
     * @param: response
     * @param: data
     * @param: code
     * @return:
     * @throws:
     */
    protected void write(HttpServletResponse response, Object data, String code) {
        try {
            // 如果没有返回码，则返回默认的系统内部异常
            if (StringUtils.isEmpty(code)) {
                code = ErrorCodeEnum.ERROR_INTERNAL_CODE.name();
            }

            // 封装数据
            String responseMsg = "";
            if (data != null) {
                Map<String, Object> responseMap = new HashMap<String, Object>();
                responseMap.put(CommonConsts.MSG_DATA, data);
                responseMap.put(CommonConsts.MSG_CODE, code);

                responseMsg = CcpFastjsonkMapper.convertObjectToString(responseMap);

                logger.info("result ", responseMsg);
            } else {
                logger.info("result ", code);
            }

            response.getOutputStream().write(responseMsg.getBytes());
            response.getOutputStream().close();
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
    }

    /**
     * @param response
     * @param report
     * @return
     * @throws
     * @Title writeExecl
     * @Description 导出execl文档
     */
    protected void writeExecl(HttpServletResponse response, CcpExcelReport report) throws Exception {
        if (report == null) {
            throw new CcpException(ErrorCodeEnum.ERROR_EXCEL_FILE_NULL);
        }

        String fileName = new String((new Date().getTime() + ".xls").getBytes(), "ISO-8859-1");

        response.reset();
        response.setContentType("application/vnd.ms-excel; charset=utf-8");
        response.setHeader("Content-Disposition", "attachment; filename=" + fileName);

        OutputStream outputStream = response.getOutputStream();
        report.write(outputStream);
        report.dispose();
    }

    /**
     * @Title: initBinder
     * @Description: 不懂
     * @param: binder
     * @return:
     * @throws:
     */
    @InitBinder
    protected void initBinder(WebDataBinder binder) {

    }
}
